using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace IntegratedOnBordDebug.UDPCore
{
    internal class UdpHelper
    {
        private readonly UdpClient _udpClient;
        private Queue<string> _received;
        private IPEndPoint _remoteEP;

        public UdpHelper(UdpClient udpClient, IPEndPoint remoteEP) {
            _udpClient = udpClient;
            _remoteEP = remoteEP;
        }

        /// <summary>
        ///   Change to your preferred enconding
        /// </summary>
        private static Encoding ChosenEncoder {
            get { return Encoding.UTF8; }
        }

        public Queue<string> Received {
            get {
                if (_received == null) {
                    _received = new Queue<string>();
                    _udpClient.BeginReceive(ReceiveCallback, null);
                }
                return _received;
            }
        }

        ~UdpHelper() {
            _udpClient.Close();
            Debug.Print("Resources freed");
        }

        public void Send(string s) {
            var packetBytes = ChosenEncoder.GetBytes(s);
            Send(packetBytes);
        }

        public void Send(byte[] s)
        {
            _udpClient.Send(s, s.Length, _remoteEP);
            // _udpClient.BeginSend(packetBytes, packetBytes.Length, _remoteEP,null,null); // could receive broken packets
            Debug.Print(string.Format("Message sent from {0} on port {1}", _remoteEP.Address, _remoteEP.Port));
        }

        private void ReceiveCallback(IAsyncResult ar) {
            IPEndPoint epRemote = null;
            var receiveBytes = _udpClient.EndReceive(ar, ref epRemote);
            Debug.Print(string.Format("Message received from {0} on port {1}", epRemote.Address, epRemote.Port));
            _received.Enqueue(ChosenEncoder.GetString(receiveBytes));
            _udpClient.BeginReceive(ReceiveCallback, null);
        }
    }
}